﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Aop.Api;
using Aop.Api.Domain;
using Aop.Api.Request;
using Coldairarrow.Business;
using Coldairarrow.Entity;
using Coldairarrow.Entity.Backstage.TheRules;
using Coldairarrow.Entity.Backstage.UserData;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.Entity.Order;
using Coldairarrow.Entity.Pay;
using Coldairarrow.IBusiness.Order;
using Coldairarrow.Util;
using Coldairarrow.Util.Pay.AlipayPay;
using EFCore.Sharding;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using WxPayAPI;

namespace Coldairarrow.Api.Controllers.Order
{
    [Route("/Order/[controller]/[action]")]
    public class BTB_RefundMasterController : BaseApiController
    {
        #region DI
        public readonly IWebHostEnvironment _webHostEnvironment;
        public BTB_RefundMasterController(IBTB_RefundMasterBusiness bTB_RefundMasterBusiness, IDbAccessor db, IBTB_RefundDetailsBusiness bTB_RefundDetailsBusiness, IOrder_DecimalBusiness order, IWarehouse_InformationBusiness warehouse_InformationBus, IWebHostEnvironment webHostEnvironment)
        {
            Db = db;
            _bTB_RefundMasterBusiness = bTB_RefundMasterBusiness;
            _webHostEnvironment = webHostEnvironment;
            _warehouse_InformationBus = warehouse_InformationBus;
            _order = order;
            _bTB_RefundDetailsBusiness = bTB_RefundDetailsBusiness;
        }
        IWarehouse_InformationBusiness _warehouse_InformationBus { get; }
        readonly IOrder_DecimalBusiness _order;
        private IBTB_RefundMasterBusiness _bTB_RefundMasterBusiness { get; }
        readonly IBTB_RefundDetailsBusiness _bTB_RefundDetailsBusiness;
        private IDbAccessor Db { get; }

        /// <summary>
        /// 添加退款订单
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [NoCheckJWT]
        public async Task SetToData(SetRefundOderDTO data)
        {
            await _bTB_RefundMasterBusiness.AddDataAsync(data);
        }

        [HttpPost]
        [NoCheckJWT]
        public async Task<PageResult<BTB_RefundDTO>> GetGoodsList(PageInput<BTB_RefundDTO> input)
        {
            return await _bTB_RefundMasterBusiness.GetGoodsList(input);
        }

        /// <summary>
        /// 后台——获取退款申请列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResult<GetRefundOderDTO>> GetOrdersList(PageInput<SearchDTO> input)
        {
            return await _bTB_RefundMasterBusiness.GetOrdersListAsnyc(input);
        }


        /// <summary>
        /// 后台——获取退款申请详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<RefundOrderDto> GetTheData(IdInputDTO input)
        {
            return await _bTB_RefundMasterBusiness.GetTheDataAsnyc(input);
        }


        /// <summary>
        /// 后台——审核退款（通过即退款）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task SPRefundAsync(SPRefundDTO input)
        {
            BTB_RefundMaster data = new BTB_RefundMaster();
            var dList = Db.GetIQueryable<BTB_RefundMaster>().Where(x => x.Id.Equals(input.Id) && x.State == 0).ToList();
            if (dList.Count > 0)
            {
                data = dList[0];
                var OrderMast = Db.GetIQueryable<Order_Master>().Where(q => q.Id == data.OrderId && q.PayState > 0 && q.OrderState == 7).ToList();
                if (OrderMast.Count > 0 && input.State == 1)
                {
                    if (data.PayState == 1)
                    {
                        var cert = new Config.certParams();
                        //设置证书相关参数
                        CertParams certParams = new CertParams
                        {
                            AlipayPublicCertPath = _webHostEnvironment.WebRootPath + cert.AlipayPublicCertPath,
                            AppCertPath = _webHostEnvironment.WebRootPath + cert.AppCertPath,
                            RootCertPath = _webHostEnvironment.WebRootPath + cert.RootCertPath
                        };


                        DefaultAopClient client = new DefaultAopClient(Configs.gatewayUrl, Configs.app_id, Configs.private_key, "json", "2.0",
                           Configs.sign_type, Configs.charset, false, certParams);

                        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
                        model.OutTradeNo = data.OrderId;
                        model.OutRequestNo = data.Id;
                        model.RefundAmount = OrderMast[0].TotalPrice.ToString();
                        //model.RefundAmount = "0.01";
                        model.RefundReason = data.Resion;

                        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
                        request.SetBizModel(model);

                        var response = client.CertificateExecute(request);
                        JObject studentsJson = JObject.Parse(response.Body);
                        Serilog.Log.Information("ZFBTK.result_code" + studentsJson.ToJson().ToString());
                        string aa = studentsJson["alipay_trade_refund_response"]["code"].ToString();
                        if (aa == "10000")
                        {
                            var RefundDetails = Db.GetIQueryable<BTB_RefundDetails>().Where(q => q.MasterId == data.Id).ToList();

                            //反向入库
                            foreach (var item in RefundDetails)
                            {
                                RefundDetails[0].State = 1;
                                await _bTB_RefundDetailsBusiness.UpdateAsync(RefundDetails[0]);
                                var order = Db.GetIQueryable<Order_Decimal>().Where(q => q.Id == item.Order_DecimalId).ToList();
                                Serilog.Log.Information("ZFBTK.order.Length" + order.Count);
                                order[0].IsRefund = 2;
                                await _order.UpdateDataAsync(order[0]);

                                //var order2 = Db.GetIQueryable<Order_Decimal>().Where(q => q.OrderMaster_Id == RefundDetails[0].OrderId).ToList();
                                //入库逻辑代码
                                Warehouse_Information data1 = new Warehouse_Information()
                                {
                                    Product_Id = order[0].Product_Id,
                                    Num = RefundDetails[0].Num,
                                    Products_Id = order[0].Products_Id,
                                };
                                await _warehouse_InformationBus.AddDataTwoAsync(data1);
                            }

                            #region//扣除收益
                            var oModel = OrderMast[0];
                            //查询上级人员
                            var theUser = Db.GetIQueryable<BTB_StaffUser>().Where(x => x.id.Equals(oModel.CreatorId)).ToList();
                            if (theUser.Count > 0)
                            {
                                var sjUser = Db.GetIQueryable<BTB_StaffUser>().Where(x => x.User_YQCode.Equals(theUser[0].User_BYQCode)).ToList();
                                if (sjUser.Count > 0)
                                {
                                    //获取所有商品
                                    var gList = Db.GetIQueryable<Order_Decimal>().Where(x => x.OrderMaster_Id.Equals(oModel.Id)).ToList();
                                    decimal syNum = 0;

                                    //查询所有商品返利记录扣除所有返利金额
                                    List<BS_UserRebate> uList = new List<BS_UserRebate>();
                                    foreach (var item in gList)
                                    {
                                        var rbModel = Db.GetIQueryable<BS_UserRebate>().Where(x => x.OrderId.Equals(oModel.Id) && x.GoodsId.Equals(item.Products_Id) && x.XFUserId.Equals(theUser[0].id)).ToList();
                                        if (rbModel.Count > 0)
                                        {
                                            var rMoney = -1 * rbModel[0].ReturnMoney;

                                            BS_UserRebate fmodel = new BS_UserRebate();
                                            fmodel.Id = IdHelper.GetId();
                                            fmodel.Deleted = false;
                                            fmodel.CreatorId = theUser[0].id;
                                            fmodel.CreateTime = DateTime.Now;
                                            fmodel.SUserId = sjUser[0].id;
                                            fmodel.XFUserId = theUser[0].id;
                                            fmodel.OrderId = oModel.Id;
                                            fmodel.GoodsId = item.Products_Id;
                                            fmodel.ReturnDiscount = rbModel[0].ReturnDiscount;
                                            fmodel.OrderMoney = (decimal)item.SumProducts;
                                            fmodel.Type = 1;
                                            fmodel.GoodsName = item.ProductNames;
                                            fmodel.GoodsItemName = item.ProductitemNames;
                                            fmodel.GoodsPrice = item.ProductPrice;
                                            fmodel.GoodsNum = item.Products_Num;
                                            fmodel.Note = theUser[0].NickName.Substring(0, 1) + "*退货" + item.ProductitemNames + "收益回扣";
                                            fmodel.ReturnMoney = rMoney;
                                            syNum += rMoney;
                                            uList.Add(fmodel);
                                        }
                                    }

                                    var upMList = Db.GetIQueryable<BS_UserICPoint>().Where(x => x.UserId.Equals(sjUser[0].id)).ToList();
                                    if (upMList.Count > 0)
                                    {

                                        upMList[0].Income += syNum;
                                        if (upMList[0].Income < 0)
                                        {
                                            upMList[0].Income = 0;
                                        }

                                        await Db.UpdateAsync(upMList[0]);
                                        await Db.InsertAsync(uList);
                                    }
                                    else
                                    {
                                        BS_UserICPoint upModel = new BS_UserICPoint();
                                        upModel.Id = IdHelper.GetId();
                                        upModel.Deleted = false;
                                        upModel.CreatorId = theUser[0].id;
                                        upModel.CreateTime = DateTime.Now;
                                        upModel.UserId = sjUser[0].id;
                                        upModel.Income = 0;
                                        upModel.Point = 0;

                                        await Db.InsertAsync(upModel);
                                        await Db.InsertAsync(uList);
                                    }
                                }
                            }
                            #endregion

                            OrderMast[0].OrderState = 8;
                            await Db.UpdateAsync(OrderMast[0]);
                        }
                        else
                        {
                            data.State = -2;
                            await Db.UpdateAsync(data);
                            throw new BusException("退款出现异常，请核对订单号及金额");
                        }
                    }
                    else if (data.PayState == 2 || data.PayState == 3)
                    {
                        var oederid = data.OrderId;
                        var SumPrice = OrderMast[0].TotalPrice;

                        var WeChatParamet = Db.GetIQueryable<WeChatParameter>(true).Where(q => q._Orderid == data.OrderId).ToList();
                        if (SumPrice > 0 && WeChatParamet[0]._Orderid != "")
                        {

                            Util.lib.PayNum payNum = new Util.lib.PayNum();

                            int total_fee = Convert.ToInt32(SumPrice * 100);
                            //int total_fee = 1;

                            Serilog.Log.Information("使用扫码支付");
                            WxPayData data2 = new WxPayData();
                            data2.SetValue("total_fee", total_fee);//订单总金额
                            data2.SetValue("refund_desc", data.Resion);//退款原因
                            data2.SetValue("refund_fee", total_fee);//退款金额
                            data2.SetValue("transaction_id", WeChatParamet[0].transaction_id);//微信订单id
                            data2.SetValue("out_refund_no", WxPayApi.GenerateOutTradeNo());//随机生成商户退款单号
                            data2.SetValue("op_user_id", WxPayConfig.GetConfig().GetMchID());//操作员，默认为商户号
                            WxPayData result = WxPayApi.Refund(data2, _webHostEnvironment.WebRootPath);//提交退款申请给API，接收返回数据
                            var result_code = result.GetValue("result_code");
                            var return_code = result.GetValue("return_code");
                            var err_code_des = result.GetValue("err_code_des");
                            Serilog.Log.Information("WXTK.result_code" + result_code.ToString());
                            Serilog.Log.Information("WXTK.return_code" + return_code.ToString());
                            //Serilog.Log.Information("WXTK.err_code_des" + err_code_des.ToString());
                            if (result_code.ToString() == "SUCCESS" && return_code.ToString() == "SUCCESS")
                            {
                                var RefundDetails = Db.GetIQueryable<BTB_RefundDetails>().Where(q => q.MasterId == data.Id).ToList();

                                //反向入库
                                foreach (var item in RefundDetails)
                                {
                                    RefundDetails[0].State = 1;
                                    await _bTB_RefundDetailsBusiness.UpdateAsync(RefundDetails[0]);
                                    var order = Db.GetIQueryable<Order_Decimal>().Where(q => q.Id == item.Order_DecimalId).ToList();
                                    Serilog.Log.Information("WXTK.order.Length" + order.Count);
                                    order[0].IsRefund = 2;
                                    await _order.UpdateDataAsync(order[0]);

                                    //var order2 = Db.GetIQueryable<Order_Decimal>().Where(q => q.OrderMaster_Id == RefundDetails[0].OrderId).ToList();
                                    //入库逻辑代码
                                    Warehouse_Information data1 = new Warehouse_Information()
                                    {
                                        Product_Id = order[0].Product_Id,
                                        Num = RefundDetails[0].Num,
                                        Products_Id = order[0].Products_Id,
                                    };
                                    await _warehouse_InformationBus.AddDataTwoAsync(data1);
                                }

                                #region//扣除收益
                                var oModel = OrderMast[0];
                                //查询上级人员
                                var theUser = Db.GetIQueryable<BTB_StaffUser>().Where(x => x.id.Equals(oModel.CreatorId)).ToList();
                                if (theUser.Count > 0)
                                {
                                    var sjUser = Db.GetIQueryable<BTB_StaffUser>().Where(x => x.User_YQCode.Equals(theUser[0].User_BYQCode)).ToList();
                                    if (sjUser.Count > 0)
                                    {
                                        //获取所有商品
                                        var gList = Db.GetIQueryable<Order_Decimal>().Where(x => x.OrderMaster_Id.Equals(oModel.Id)).ToList();
                                        decimal syNum = 0;

                                        //查询所有商品返利记录扣除所有返利金额
                                        List<BS_UserRebate> uList = new List<BS_UserRebate>();
                                        foreach (var item in gList)
                                        {
                                            var rbModel = Db.GetIQueryable<BS_UserRebate>().Where(x => x.OrderId.Equals(oModel.Id) && x.GoodsId.Equals(item.Products_Id) && x.XFUserId.Equals(theUser[0].id)).ToList();
                                            if (rbModel.Count > 0)
                                            {
                                                var rMoney = -1 * rbModel[0].ReturnMoney;

                                                BS_UserRebate fmodel = new BS_UserRebate();
                                                fmodel.Id = IdHelper.GetId();
                                                fmodel.Deleted = false;
                                                fmodel.CreatorId = theUser[0].id;
                                                fmodel.CreateTime = DateTime.Now;
                                                fmodel.SUserId = sjUser[0].id;
                                                fmodel.XFUserId = theUser[0].id;
                                                fmodel.OrderId = oModel.Id;
                                                fmodel.GoodsId = item.Products_Id;
                                                fmodel.ReturnDiscount = rbModel[0].ReturnDiscount;
                                                fmodel.OrderMoney = (decimal)item.SumProducts;
                                                fmodel.GoodsName = item.ProductNames;
                                                fmodel.GoodsItemName = item.ProductitemNames;
                                                fmodel.GoodsPrice = item.ProductPrice;
                                                fmodel.GoodsNum = item.Products_Num;
                                                fmodel.Type = 0;
                                                fmodel.Note = theUser[0].NickName.Substring(0, 1) + "*退货" + item.ProductitemNames + "收益回扣";
                                                fmodel.ReturnMoney = rMoney;
                                                syNum += rMoney;
                                                uList.Add(fmodel);
                                            }
                                        }

                                        var upMList = Db.GetIQueryable<BS_UserICPoint>().Where(x => x.UserId.Equals(sjUser[0].id)).ToList();
                                        if (upMList.Count > 0)
                                        {

                                            upMList[0].Income += syNum;
                                            if (upMList[0].Income < 0)
                                            {
                                                upMList[0].Income = 0;
                                            }

                                            await Db.UpdateAsync(upMList[0]);
                                            await Db.InsertAsync(uList);
                                        }
                                        else
                                        {
                                            BS_UserICPoint upModel = new BS_UserICPoint();
                                            upModel.Id = IdHelper.GetId();
                                            upModel.Deleted = false;
                                            upModel.CreatorId = theUser[0].id;
                                            upModel.CreateTime = DateTime.Now;
                                            upModel.UserId = sjUser[0].id;
                                            upModel.Income = 0;
                                            upModel.Point = 0;

                                            await Db.InsertAsync(upModel);
                                            await Db.InsertAsync(uList);
                                        }
                                    }
                                }
                                #endregion

                                OrderMast[0].OrderState = 8;
                                await Db.UpdateAsync(OrderMast[0]);
                            }
                            else
                            {
                                throw new BusException("退款订单出现异常，请联系管理员");
                            }
                        }
                        else
                        {
                            data.State = -2;
                            await Db.UpdateAsync(data);
                            throw new BusException("退款出现异常，请核对订单号及金额");
                        }

                    }
                    else
                    {
                        throw new BusException("订单支付方式不支持线上退款，请核对订单信息！");
                    }

                    data.State = 1;
                    await Db.UpdateAsync(data);
                }
                else if (OrderMast.Count > 0 && input.State != 1)
                {
                    data.State = -1;
                    data.NoPassResion = input.NoPassResion;
                    await Db.UpdateAsync(data);

                    OrderMast[0].OrderState = 9;
                    await Db.UpdateAsync(OrderMast[0]);
                }
                else
                {
                    throw new BusException("订单查询失败，请核对信息！");
                }
            }
            else
            {
                throw new BusException("该退款信息状态错误，退款失败，请确认信息");
            }
        }

        #endregion
    }
}
